/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pa165.dominatingspecies.rest;

import java.net.URI;

import java.util.List;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.GenericEntity;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import org.springframework.dao.DataAccessException;
import org.springframework.security.access.prepost.PreAuthorize;
import pa165.dominating.species.enums.ElementType;


import pa165.dominating.species.service.ElementService;
import pa165.dominating.species.tos.ElementTo;

/**
 *
 * @author Ondrej Prazak
 */
 
@Path("/elements")
public class ElementRestService {   
    
    private ElementService elementService;
    
    @Context
    private UriInfo context;
    
    
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @PreAuthorize("hasRole('WORKER')")
    public Response getAllElements(){      
      List<ElementTo> found = elementService.getAllElementTos();
      GenericEntity<List<ElementTo>> all = new GenericEntity<List<ElementTo>>(found){};
      return Response.ok(all).build();
    }
    
    @GET
    @Path("{id}")
    @Produces(MediaType.APPLICATION_JSON)
    @PreAuthorize("hasRole('WORKER')")
    public ElementTo getElementById(@PathParam("id") Long id){          
         return elementService.getElementToById(id);         
    }
    
    @GET
    @Path("types/{type}")
    @Produces(MediaType.APPLICATION_JSON)
    @PreAuthorize("hasRole('WORKER')")
    public ElementTo getElementByType(@PathParam("type") ElementType type){
      return elementService.getElementToByType(type);
    }
    
    @POST
    @Path("create")
    @Consumes(MediaType.APPLICATION_JSON) 
    @Produces(MediaType.APPLICATION_JSON)
    @PreAuthorize("hasRole('ADMIN')")
    public Response createElement(ElementTo to){
      boolean thrown = false;
      String msg = null;
      try{
       elementService.createElement(to);
      }
      catch(DataAccessException ex){
        thrown = true;
        msg = ex.getMessage();
      }
      if(thrown){
          System.out.println(msg);
        return Response.status(404).entity(msg).build();
      }
      else{
        List<ElementTo> found = elementService.getAllElementTos();
        Long key = elementService.getElementToById(found.get(found.size() - 1).getId()).getId();
        return Response.created(URI.create(context.getAbsolutePath() + "/" + key)).build();
      }     
    }


    @DELETE
    @Path("delete/{id}")
    @PreAuthorize("hasRole('ADMIN')")
    public Response deleteElement(@PathParam("id") Long id){
      boolean thrown = false;
      try{
        elementService.deleteElement(elementService.getElementToById(id));
      }
      catch(DataAccessException ex){
        thrown = true;
      }
      if(thrown){
        return Response.status(404).entity("Element with id '" + id +"' cannot be deleted.").build();
      }
      else{
        return Response.status(200).entity("Element with id '" + id +"' was successfuly deleted.").build();
      }      
    }
    
    @PUT
    @Path("update")
    @Consumes(MediaType.APPLICATION_JSON) 
    @Produces(MediaType.APPLICATION_JSON)
    @PreAuthorize("hasRole('WORKER')")
    public Response updateElement(ElementTo to){
      ElementTo found = elementService.getElementToById(to.getId());
      found.setDescription(to.getDescription());
      found.setType(to.getType());
      
      boolean thrown = false;
      try{
       elementService.updateElementTo(found);
      }
      catch(DataAccessException ex){
        thrown = true;
      }
      if(!thrown){
        return Response.ok(elementService.getElementToById(found.getId())).build();
      }
      else{
        return Response.status(404).entity("Element with given type already exists.").build();
      }
      
    }

    public void setElementService(ElementService elementService) {
        this.elementService = elementService;
    }
    
    
    
}
